const jwt = require("jsonwebtoken");
const { createUser, getUserInfo, updateById } = require("../service/user.service");
const { userRegisterError, modifyPasswordFail, modifyPasswordError } = require("../constant/error.type");
const { JWT_SECRET } = require("../config/config.default");

class UserController {
  // 数据库等的一些操作是异步的，所以定义异步的方法
  /**
   * 用户注册
   * @param {*} ctx 请求上下文
   * @param {*} next 放行函数
   */
  async register(ctx, next) {
    try {
      // 1.获取数据
      console.log(ctx.request.body);
      const { user_name, password } = ctx.request.body;
      // 2.操作数据库
      const res = await createUser(user_name, password);
      // console.log(res);
      // 3.返回结果
      ctx.body = {
        code: 0,
        massage: "用户注册成功",
        result: {
          id: res.id,
          user_name: res.user_name,
        },
      };
    } catch (error) {
      console.log(error);
      ctx.app.emit("error", userRegisterError, ctx);
    }
  }

  /**
   * 用户登录
   * @param {*} ctx 请求上下文
   * @param {*} next 放行函数
   */
  async login(ctx, next) {
    try {
      // 1.获取用户信息（在token的payload中，要记录id，user_name，is_admin）
      const { user_name } = ctx.request.body;
      // 从返回的结果对象中剔除password属性，将剩余的属性放到res对象中，避免后面的jwt载荷包含密码
      const { password, ...res } = await getUserInfo({ user_name });
      // console.log("res", res);
      ctx.body = {
        code: 0,
        massage: "用户登录成功",
        result: {
          /**
           * 使用JWT对用户信息进行签名，避免被篡改
           * jwt.sign的参数
           * 第一个参数：载荷
           * 第二个参数：秘钥
           * 第三个参数：配置项：可配置过期时间expiresIn
           */
          token: jwt.sign(res, JWT_SECRET, {
            expiresIn: "1d", // 1d: 表示一天后过期；1m: 表示一分钟后过期；10s: 表示10秒钟后过期
          }),
          user_name: res.user_name,
        },
      };
    } catch (error) {
      console.error("用户登录失败", error);
    }
  }

  /**
   * 修改密码
   * @param {*} ctx 请求上下文
   * @param {*} next 放行函数
   */
  async modifyPassword(ctx, next) {
    try {
      // 1.获取数据
      const id = ctx.state.user.id;
      const password = ctx.request.body.password;
      // 2.操作数据库（调用service操作数据库）
      const res = await updateById({ id, password });
      // console.log("res", res);
      // 3.返回结果
      if (res) {
        ctx.body = {
          code: 0,
          massage: "修改密码成功",
          result: "",
        };
      } else {
        console.error("修改密码失败", res);
        ctx.app.emit("error", modifyPasswordFail, ctx);
      }
    } catch (error) {
      console.error("修改密码出错", error);
      ctx.app.emit("error", modifyPasswordError, ctx);
    }
  }
}

module.exports = new UserController();
